from django.views import View
from django import http
from django_redis import get_redis_connection

import re
import logging
import json
import random

from apps.verifications.libs.captcha.captcha import captcha
from apps.verifications.libs.yuntongxun.ccp_sms import sendTemplateSMS
from utils import constants
from utils.response_code import RET


# 创建日志输出器
logger = logging.getLogger("django")


class ImageCodeView(View):
    """
    获取图片验证码
    """

    def get(self,request):

        # 1. 接收参数
        cur_uuid = request.GET.get("cur")
        pre_uuid = request.GET.get("pre")

        # 2. 校验参数
        if not cur_uuid:
            return http.HttpResponseForbidden("参数不全")

        if not re.match(r"\w{8}(-\w{4}){3}-\w{12}", cur_uuid):
            return http.HttpResponseForbidden("参数格式不正确")

        if not re.match(r"\w{8}(-\w{4}){3}-\w{12}", pre_uuid):
            return http.HttpResponseForbidden("参数格式不正确")

        # 3. 生成验证码
        #text: 生成图片验证码的内容  image: 图片二进制
        text,image = captcha.generate_captcha()
        logger.info("验证码: %s" % text)

        # 4. 连接Redis数据库
        redis_conn = get_redis_connection("verify_code")
        try:
            # 保存当前的验证码编号
            # redis_conn.setex('key', '过期时间,单位秒', 'value')
            redis_conn.setex("ImageCode_" + cur_uuid, constants.IMAGE_CODE_REDIS_EXPIRES,text)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseServerError("生成图片验证码失败")
        else:
            return http.HttpResponse(image,content_type="image/jpg")


class SMSCodeView(View):
    """
    获取短信验证码
    """
    def post(self,request):

        # 接收参数
        dict_data = json.loads(request.body.decode())
        mobile = dict_data.get("mobile")
        image_code_id = dict_data.get("id")
        image_code = dict_data.get("text")

        # 提取并判断发送短信验证码的标记是否存在,如果标记存在表示发送短信验证码过于频繁
        redis_conn = get_redis_connection("verify_code")
        sms_code_flag = redis_conn.get("sms_code_flag_%s" % mobile)
        if sms_code_flag:
            return http.JsonResponse({"error":RET.REQERR,"errmsg":"请求过于频繁"})
        # 校验参数是否齐全
        if not all([mobile,image_code,image_code_id]):
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"参数错误"})
        # 校验手机号
        if not re.match(r"1[3-8]\d{9}",mobile):
            return http.JsonResponse({"errno":RET.PARAMERR,"errmsg":"参数错误"})

        real_image_code = redis_conn.get("ImageCode_%s" % image_code_id)

        # 提取图形验证码
        if not real_image_code:
            return http.JsonResponse({"errno":RET.NODATA,"errmsg":"验证码已过期"})
        # 删除图形验证码:防止恶意用户行为操作
        redis_conn.delete("ImageCode_" + image_code_id)
        # 对比图形验证码
        # 把bytes类型的image_code 转换成str 类型
        if image_code.lower() != real_image_code.decode().lower():
            return http.JsonResponse({"errno":RET.DATAERR,"errmsg":"验证输入有误"})

        # 生成短信验证码
        sms_code = "%06d" % random.randint(0,999999)
        logger.info("短信验证码:%s" % sms_code)

        # 短信验证码保存到Redis
        # 创建管道
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES,sms_code)
        # 避免过于频繁,为发短信添加标记
        pl.setex("sms_code_flag_%s" % mobile,constants.SEND_SMS_CODE_INTERVAL,"flag")
        pl.execute()

        # 发送短信
        # try:
        #     result =sendTemplateSMS(mobile,[sms_code,constants.SMS_CODE_REDIS_EXPIRES // 60],1)
        #     if result != 0:
        #         return http.JsonResponse({"errno": RET.THIRDERR, "errmsg": "第三方系统出错"})
        # except Exception as e:
        #     logger.error(e)
        #     return http.JsonResponse({"errno": RET.UNKOWNERR, "errmsg": "未知错误"})
        sendTemplateSMS(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], 1)

        # 返回响应
        return http.JsonResponse({'errno': RET.OK, 'errmsg': '发送短信成功'})
